////////////////////////////////////////
// bookFlights.cpp
// This is a simple flight reservation system.
// Name: Stephen Durfey
// Class: CS335
// Time: TR 1:00 - 2:15pm
/*
 *To solve the issue surrounding invalid input data from the user, I went 
 *about the problem in a couple of different ways. Primarily, whenever the 
 *program was to expect integer values from the user, I used C-strings to
 *store the input from the user, and passed that C-string to the function
 *'returnDigit(char choice[])'. The function is described in detail at the
 *bottom of this source code. If a user entered a non-digit character or a 
 *string, the program would default into an infinite loop. This function solves
 *that issue. 
 *
 *Another problem that would be encountered is if the user entered any lower
 *case letters when typing in the airline code, the origination, and desination
 *of the flight, a match would not be found in the program, because the values
 *are read into the program as uppercase variables. To ensure consistency 
 *throughout the program, I also ensured that the strings read in from the data
 *file are also in all uppercase. I wrote a simple function called, 'upperCase()'
 *and is detailed in the comment section above the function definition.
 *
 *The last major robustness identified was what if the file wasnt there, or
 *wouldn't open properly? If the data file cannot be read from, then the program
 *is useless to the user. So in the member function 'readFlights()' a simple
 *if-else statement was employed. If the file opens properly, the rest of the program
 *will run smoothly, else the program informs the user it was unable to open
 *the file, and the program will exit.
 *****************************************************************************/

#include <iostream>
#include <fstream>
#include <cctype>
#include <cstring>
#include "bookFlights.h"

using namespace std;

int main()
{
    Flight      flights[MAX_FLIGHTS];
    int         flightIdx[MAX_MATCHING_FLIGHTS];
    int         nFlights, nIdx = 0, iFlight, conChoice, flightChoice;
    ifstream    flightFile("flights.txt");
    string      orig, dest, airline;
    char        choice[MAX], flightNum[MAX];
  
    nFlights = readFlights(flights, flightFile);

    cout << "Welcome to the Airline Reservation System." << endl;
    do
    {
        cout << endl;
        cout << "What would you like to do?" << endl;
        cout << "1) SEARCH FLIGHTS" << endl;
        cout << "2) BOOK CHEAPEST FLIGHT AMONG LAST SEARCHED" << endl;
        cout << "3) BOOK SPECIFIC FLIGHT" << endl;
        cout << "4) QUIT" << endl;
        cout << endl;
        cin.getline(choice, MAX);
        
        conChoice = returnDigit(choice);
        
        if(conChoice != -1)
        {
            switch (conChoice)
            {
                case 1:
                    cout << "Enter origin code and destination code (origin dest): ";
                    cin >> orig >> dest;
                    cin.ignore();
                    upperCase(orig);
                    upperCase(dest);
                    
                    nIdx = searchFlights(flightIdx,flights, nFlights, orig, dest);
                    sortFlightIdx(flightIdx, nIdx, flights);
                    printFlights(flightIdx, nIdx, flights);
                    break;

                case 2:
                    if (nIdx <= 0)
                        cout << "no or unsuccessful previous search" << endl;
                    else
                        getSeatsBookFlight(flights[flightIdx[0]]);
                    break;

                case 3:
                    cout << "Enter airline code: ";
                    cin >> airline;
                    cin.ignore();
                    cout << "Enter Flight Number: ";
                    cin.getline(flightNum, MAX);
            
                    upperCase(airline);
                    flightChoice = returnDigit(flightNum);
            
                    if(flightChoice != -1)
                    {
                        if ((iFlight = searchFlight(flights, nFlights, airline, flightChoice)) < 0)
                        {
                            cout << airline << " " << flightNum << ": no such flight" << endl;
                        }
                        else
                            getSeatsBookFlight(flights[iFlight]);
                    }
                    else
                    {
                        cout << "Invalid data, request not processed\n";
                    }
                    break;
            
                case 4:
                    cout << "quitting" << endl;
                    break;

                default:
                    cout << "incorrect option" << endl;
                }
        }
        else
        {
            cout << "Invalid Data\n";
        }
    } while (conChoice != 4);

    return 0;
}

////////////////////////////////////////
// 'getSeatsBookFlight' prompts for number of seats
//     and tries to book them
// displays error message if not enough seats remaining

void getSeatsBookFlight(Flight & flight)
{
    char     nSeats[MAX];
    int      numSeats;

    cout << "Enter number of seats to book: ";
    cin.getline(nSeats, 20);
    numSeats = returnDigit(nSeats);
    
    if(numSeats > -1)
    {    
        if (bookFlight(flight, numSeats))
            cout << "done" << endl;
        else
            cout << "cannot book " << nSeats << " seats" << endl;
    }
    else
        cout << "Invalid data entered, request not processed\n";
}

/*******************************************************
 *function 'upperCase' ensures that the data entered   
 *by the user is in all uppercase. If any of the 
 *letters are in lowercase, then 'searchFlights()'
 *or 'searchFlight() will not be able to properly
 *handle the data passed to it. 
 *
 *the function 'toupper()' belongs to the 'cctype' 
 *header file.
 *******************************************************/

void upperCase(string &code)
{
    for(unsigned int index = 0; index < code.length(); index++)
    {
        code[index] = toupper(code[index]);
    }
}

/*****************************************************************
 *this function ensures the user entered the proper data. 
 *this prevents the program from entering an infinite loop if
 *the user enters a character or a string as an option, and
 *it weeds out negative input values. It accepts
 *a char array parameter. A while loop is used to check each
 *char in the array to verify it is a digit, using 'isdigit()'. 
 *If any non-digit characters are found in the array, a -1 is
 *returned to indicate the input is not valid. If the array is all
 *digits, then function 'atoi()' is used to convert the char array into
 *an integer. 'ascNum' is used to hold that integer and is returned
 *if the entire array are digits.
 *****************************************************************/

int returnDigit(char choice[])
{     
    bool alpha = false;
    int index = 0, ascNum;
    
    while(choice[index] != '\0' && !alpha)
    {
        if(!isdigit(choice[index]))
            alpha = true;
        index++;
    }
    
    if(!alpha)
    {
        ascNum = atoi(choice);
        return ascNum;
    }    
    else
        return -1;
}


